package random.generators;

import java.util.ArrayList;
import java.util.List;

public class GaussianDistributionGenerator implements
		DistributionGenerator {
	double mean;
	double squaredStdDeviation;

	public GaussianDistributionGenerator(double mean,
			double squaredStdDeviation) {
		this.mean = mean;
		this.squaredStdDeviation = squaredStdDeviation;
	}

	public List<Double> generateRandomNumbers(int n) {
		List<Double> ans = new ArrayList<Double>();
		double x1, x2;
		for (int i = 0; i < n; i++) {
			x1 = Math.random(); // x1 variable uniforme en el 0-1
			x2 = Math.random(); // x2 variable uniforme en el 01

			double y1 = y1(x1, x2);
			double y2 = y2(x1, x2);

			/*
			 * double p1 = ((double) 1 / Math.sqrt(sigmaCuadrado * 2 * Math.PI))
			 * Math.exp(-(0.5) Math.pow((y1 - media) / Math.sqrt(sigmaCuadrado),
			 * 2)); double p2 = ((double) 1 / Math.sqrt(sigmaCuadrado * 2 *
			 * Math.PI)) Math.exp(-(0.5) Math.pow((y2 - media) /
			 * Math.sqrt(sigmaCuadrado), 2)); ans.add(p1 * p2);
			 */
			ans.add(y1);
			//ans.add(y2);
		}

		return ans;
	}

	private double y1(double x1, double x2) {
		return mean + Math.sqrt(squaredStdDeviation) * Math.sqrt(-2 * Math.log(x1)) * Math.cos(2 * Math.PI * x2);
	}

	private double y2(double x1, double x2) {
		return mean + Math.sqrt(squaredStdDeviation) * Math.sqrt(-2 * Math.log(x1)) * Math.sin(2 * Math.PI * x2);
	}

	public Double distributionFunction(double y) {
		double constant, exponent;

		constant = (double) 1 / Math.sqrt(squaredStdDeviation * 2 * Math.PI);
		double exp = (double) (y - mean) / Math.sqrt(squaredStdDeviation);
		exponent = (double) 0.5 * Math.pow(exp, 2);
		double ret = constant * Math.exp(-exponent);
		return ret;
	}

}
